{
    "AWSTemplateFormatVersion": "2010-09-09",
    "Description": "Lambda Function resource stack creation using Amplify CLI",
    "Parameters": {
        "CloudWatchRule": {
            "Type": "String",
            "Default" : "NONE",
            "Description" : " Schedule Expression"
        },
        "deploymentBucketName": {
            "Type": "String"
        },
        "env": {
            "Type": "String"
        },
        "s3Key": {
            "Type": "String"
        }<% if (props.environmentVariables) { %>
        <% for(var i = 0; Object.keys(props.environmentVariables).length > i; i++) { %>
        ,
        "<%- props.environmentMap[Object.keys(props.environmentVariables)[i]].Ref %>": {
            "Type": "String"
        }
        <% } %>
        <% } %>
        <%if (props.dependsOn && props.dependsOn.length > 0) { %>,<% } %>
    <% if (props.dependsOn) { %>
    <% for(var i=0; i < props.dependsOn.length; i++) { %>
    <% for(var j=0; j < props.dependsOn[i].attributes.length; j++) { %>
        "<%= props.dependsOn[i].category %><%= props.dependsOn[i].resourceName %><%= props.dependsOn[i].attributes[j] %>": {
            "Type": "String",
            "Default": "<%= props.dependsOn[i].category %><%= props.dependsOn[i].resourceName %><%= props.dependsOn[i].attributes[j] %>"
            }<%if (i !== props.dependsOn.length - 1 || j !== props.dependsOn[i].attributes.length - 1 || Object.keys(props.dependsOn[i].exports || {}).length > 0) { %>,<% } %>
        <% } %>
    <% for(var j=0; j < Object.keys(props.dependsOn[i].exports || {}).length; j++) { %>
        "<%= Object.keys(props.dependsOn[i].exports)[j] %>": {
            "Type": "String",
            "Default": "<%= Object.keys(props.dependsOn[i].exports)[j] %>"
            }<%if (i !== props.dependsOn.length - 1 || j !== Object.keys(props.dependsOn[i].exports).length - 1) { %>,<% } %>
        <% } %>
        <% } %>
    <% } %>
    },
    "Conditions": {
        "ShouldNotCreateEnvResources": {
            "Fn::Equals": [
                {
                    "Ref": "env"
                },
                "NONE"
            ]
        }
    },
    "Resources": {
        "LambdaFunction": {
          "Type": "AWS::Lambda::Function",
          "Metadata": {
            "aws:asset:path": "./src",
            "aws:asset:property": "Code"
          },
          "Properties": {
            "Code": {
                "S3Bucket": {
                    "Ref": "deploymentBucketName"
                },
                "S3Key": {
                    "Ref": "s3Key"
                }
            },
            "Handler": "<%= props.functionTemplate.handler? props.functionTemplate.handler : props.runtime.defaultHandler %>",
            "FunctionName": {
                "Fn::If": [
                    "ShouldNotCreateEnvResources",
                    "<%= props.functionName %>",
                    {

                        "Fn::Join": [
                            "",
                            [
                                "<%= props.functionName %>",
                                "-",
                                {
                                    "Ref": "env"
                                }
                            ]
                        ]
                    }
                ]
            },
            "Environment": {
                "Variables" : <%- JSON.stringify(props.environmentMap) %>
            },
            "Role": { "Fn::GetAtt": ["LambdaExecutionRole", "Arn"] },
            "Runtime": "<%= props.runtime.cloudTemplateValue %>",
            "Layers": <%- JSON.stringify(props.lambdaLayersCFNArray) %>,
            "Timeout": 25
          }
        },
        "LambdaExecutionRole": {
            "Type": "AWS::IAM::Role",
            "Properties": {
                "RoleName": {
                    "Fn::If": [
                        "ShouldNotCreateEnvResources",
                        "<%=props.roleName %>",
                        {

                            "Fn::Join": [
                                "",
                                [
                                    "<%=props.roleName %>",
                                    "-",
                                    {
                                        "Ref": "env"
                                    }
                                ]
                            ]
                        }
                    ]
                },
                "AssumeRolePolicyDocument": {
                    "Version": "2012-10-17",
                    "Statement": [
                        {
                            "Effect": "Allow",
                            "Principal": {
                                "Service": [
                                    "lambda.amazonaws.com"
                                ]
                            },
                            "Action": [
                                "sts:AssumeRole"
                            ]
                        }
                    ]
                }
            }
        }
        ,"lambdaexecutionpolicy": {
            "DependsOn": ["LambdaExecutionRole"],
            "Type": "AWS::IAM::Policy",
            "Properties": {
                "PolicyName": "lambda-execution-policy",
                "Roles": [{ "Ref": "LambdaExecutionRole" }],
                "PolicyDocument": {
                    "Version": "2012-10-17",
                    "Statement": [
                        {
                            "Effect": "Allow",
                            "Action": ["logs:CreateLogGroup",
                            "logs:CreateLogStream",
                            "logs:PutLogEvents"],
                            "Resource": { "Fn::Sub": [ "arn:aws:logs:${region}:${account}:log-group:/aws/lambda/${lambda}:log-stream:*", { "region": {"Ref": "AWS::Region"}, "account": {"Ref": "AWS::AccountId"}, "lambda": {"Ref": "LambdaFunction"}} ]}
                        }<% if (props.functionTemplate.parameters && props.functionTemplate.parameters.database && props.functionTemplate.parameters.database.resourceName) { %>,
                        {
                            "Effect": "Allow",
                            "Action": ["dynamodb:DescribeTable","dynamodb:GetItem","dynamodb:Query","dynamodb:Scan","dynamodb:PutItem","dynamodb:UpdateItem","dynamodb:DeleteItem"],
                            "Resource": [
                            <% if (props.functionTemplate.parameters && props.functionTemplate.parameters.database && props.functionTemplate.parameters.database.Arn) { %>
                                "<%= props.functionTemplate.parameters.database.Arn %>",
                                {
                                    "Fn::Join": [
                                        "/",
                                        [
                                            "<%= props.functionTemplate.parameters.database.Arn %>",
                                            "index/*"
                                        ]
                                    ]
                                }
                            <% } else { %>
                                { "Ref": "storage<%= props.functionTemplate.parameters.database.resourceName %>Arn" },
                                {
                                    "Fn::Join": [
                                        "/",
                                        [
                                            { "Ref": "storage<%= props.functionTemplate.parameters.database.resourceName %>Arn" },
                                            "index/*"
                                        ]
                                    ]
                                }
                            <% } %>
                            ]
                        }
                        <% } %>
                    ]
                }
            }
        }<% if (props.categoryPolicies && props.categoryPolicies.length > 0 ) { %>
        ,"AmplifyResourcesPolicy": {
            "DependsOn": ["LambdaExecutionRole"],
            "Type": "AWS::IAM::Policy",
            "Properties": {
                "PolicyName": "amplify-lambda-execution-policy",
                "Roles": [{ "Ref": "LambdaExecutionRole" }],
                "PolicyDocument": {
                    "Version": "2012-10-17",
                    "Statement": <%- JSON.stringify(props.categoryPolicies) %>
                }
            }
        }
        <% } %>
        <% if (props.triggerEventSourceMappings && props.triggerEventSourceMappings.length > 0) { %>
        <% for(var i=0; i < props.triggerEventSourceMappings.length; i++) { %>
        ,"LambdaTriggerPolicy<%= props.triggerEventSourceMappings[i].modelName%>": {
            "DependsOn": ["LambdaExecutionRole"],
            "Type": "AWS::IAM::Policy",
            "Properties": {
                "PolicyName": "amplify-lambda-execution-policy-<%= props.triggerEventSourceMappings[i].modelName%>",
                "Roles": [{ "Ref": "LambdaExecutionRole" }],
                "PolicyDocument": {
                    "Version": "2012-10-17",
                    "Statement": <%- JSON.stringify(props.triggerEventSourceMappings[i].triggerPolicies) %>
                }
            }
        }
        ,"LambdaEventSourceMapping<%= props.triggerEventSourceMappings[i].modelName%>": {
            "Type": "AWS::Lambda::EventSourceMapping",
            "DependsOn": [
                "LambdaTriggerPolicy<%= props.triggerEventSourceMappings[i].modelName%>",
                "LambdaExecutionRole"
            ],
            "Properties": {
                "BatchSize": <%= props.triggerEventSourceMappings[i].batchSize %>,
                "Enabled": true,
                "EventSourceArn": <%- JSON.stringify(props.triggerEventSourceMappings[i].eventSourceArn) %>,
                "FunctionName": {
                    "Fn::GetAtt": [
                        "LambdaFunction",
                        "Arn"
                    ]
                },
                "StartingPosition": "<%= props.triggerEventSourceMappings[i].startingPosition %>"
            }
        }
        <% } %>
        <% } %>
        <% if (props.cloudwatchRule && props.cloudwatchRule != "NONE") { %>
        ,"CloudWatchEvent": {
            "Type": "AWS::Events::Rule",
            "Properties": {
                "Description": "Schedule rule for Lambda",
                "ScheduleExpression": {
                    "Ref": "CloudWatchRule"
                },
                "State": "ENABLED",
                "Targets": [{
                    "Arn": { "Fn::GetAtt": ["LambdaFunction", "Arn"] },
                    "Id": {
                        "Ref": "LambdaFunction"
                    }
                }]
            }
        }
        ,"PermissionForEventsToInvokeLambda": {
            "Type": "AWS::Lambda::Permission",
            "Properties": {
                "FunctionName": {
                    "Ref": "LambdaFunction"
                    },
                "Action": "lambda:InvokeFunction",
                "Principal": "events.amazonaws.com",
                "SourceArn": { "Fn::GetAtt": ["CloudWatchEvent", "Arn"] }
            }
        }
        <% } %>
    },
    "Outputs": {
        "Name": {
            "Value": {
                "Ref": "LambdaFunction"
            }
        },
        "Arn": {
            "Value": {"Fn::GetAtt": ["LambdaFunction", "Arn"]}
        },
        "Region": {
            "Value": {
                "Ref": "AWS::Region"
            }
        },
        "LambdaExecutionRole": {
            "Value": {
                "Ref": "LambdaExecutionRole"
            }
        }
        <% if (props.cloudwatchRule && props.cloudwatchRule != "NONE") { %>
        ,"CloudWatchEventRule": {
            "Value": {
                "Ref": "CloudWatchEvent"
            }
        }
        <% } %>
    }
}
